import re
import uuid
import sys
import os
import hashlib
def uniqid():
  return str(uuid.uuid1()).replace("-", "")
path_in = sys.argv[1]
path_out = os.path.splitext(path_in)[0] + ".pp.s"
suffix = hashlib.md5(path_in.encode()).hexdigest()
LDGP_RE = re.compile(r"\s*ldl\s*\$(?P<reg>\d+),(?P<sym>\w+)\(\$29\)\s*!literal!(?P<serial>\d*)")
JMP_RE = re.compile(r"\s*(call|jmp)\s*\$(?P<ra>\d+),\(\$(?P<addr>\d+)\),(?P<sym>\w+)\s*!lituse_jsr(direct)?!(?P<serial>\d*)")
ENT_RE = re.compile(r"\s*.ent\s+(?P<sym>\w+)")
MANGLE_RE = re.compile(r"slave__Z(?P<len>\d+)(?P<rest>.*):")
symrefs = set([])
print(path_out)
fo = open(path_out, "w")
litrefs = {}
for line in open(path_in):
  ml = LDGP_RE.match(line)
  mj = JMP_RE.match(line)
  me = ENT_RE.match(line)
  mm = MANGLE_RE.match(line)
  if ml:
    if not ml["sym"].startswith("slave_"):
      sym = "slave_" + ml["sym"]
    else:
      sym = ml["sym"]
    mark = "loadsym.%s.%s.%s" % (sym, suffix, uniqid())
    litrefs[ml["serial"]] = sym
    symrefs.add(sym)
    fo.write("\t.globl %s\n" % mark)
    fo.write("%s:\n\t" % mark)
    reg = int(ml["reg"])
    fo.write("ldi $%d, 0($31)\n\t" % reg)
    fo.write("ldih $%d, 0($%d)\n\t" % (reg, reg))
    fo.write("sll $%d, 32, $%d\n\t" % (reg, reg))
    fo.write("ldi $%d, 0($%d)\n\t" % (reg, reg))
    fo.write("ldih $%d, 0($%d)\n" % (reg, reg))
  elif mj:
    if mj["serial"] in litrefs:
      usesym = litrefs[mj["serial"]]
    else:
      usesym = mj["sym"]
    mark = "usesym.%s.%s.%s" % (usesym, suffix, uniqid())
    symrefs.add(usesym)
    fo.write("\t.globl %s\n" % mark)
    fo.write("%s:\n\t" % mark)
    ra = int(mj["ra"])
    addr = int(mj["addr"])
    fo.write("call $%d,($%d),0\n" % (ra, addr))
  elif me:
    mark = "defsym.%s.%s.%s" % (me["sym"], suffix, uniqid())
    fo.write("\t.ent %s\n" % me["sym"])
    fo.write("\t.globl %s\n" % mark)
    fo.write("%s:\n" % mark)
  elif mm:
    fo.write(line)
    length = int(mm["len"])
    rest = mm["rest"]
    remangle = "_Z%dslave_%s" % (length + len("slave_"), rest) 
    fo.write("\t.globl %s\n" % remangle)
    fo.write("%s:\n" % remangle)
  else:
    fo.write(line)
fo.write("\t.ent __gen_deps\n")
fo.write("__gen_deps:\n")
for ref in symrefs:
  fo.write("\tldl $31, %s($29) !literal\n" % ref)
fo.write("\t.end __gen_deps\n")